package com.business.lgh.naocs.naming.web;

import com.business.lgh.naocs.naming.core.ServerMemberManager;
import com.business.lgh.naocs.naming.core.pojo.Member;
import javafx.fxml.Initializable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

/**
 * @author lgh
 * @version V1.0
 * @Package com.business.lgh.naocs.naming.web
 * @date 2020/6/28 8:48 下午
 */
@Component
public class DistroMapper implements InitializingBean, ApplicationContextAware {

    @Autowired
    ServerMemberManager serverMemberManager;

    ApplicationContext applicationContext;

    List<Member> healthList;
    public static final int CAN_RESPONSE = -1;



    /**
     * 该server是否可以处理本次请求
     * @param serviceName
     * @return
     */
    public int responsible(String serviceName) {
        if (healthList==null||healthList.size()<=0){
            return CAN_RESPONSE;
        }
        //TODO 测试
        if (serviceName.contains("service-provider")){
            return healthList.size()-1;
        }
        String localAddress = serverMemberManager.getLocalAddress(applicationContext);
        int lastIndex=healthList.lastIndexOf(localAddress);
        int index=healthList.indexOf(localAddress);
        if (index<0||lastIndex<0){
            return CAN_RESPONSE;
        }
        //分片规则
        int target = distroHash(serviceName) % healthList.size();
        if (target >= index && target <= lastIndex){
            return CAN_RESPONSE;
        }else {
            return target;
        }
    }

    private int distroHash(String serviceName) {
        return Math.abs(serviceName.hashCode() % Integer.MAX_VALUE);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }

    public String getServer(int targetIndex) {
        if (targetIndex<0||targetIndex>healthList.size())
            return null;
        return healthList.get(targetIndex).getAddress();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        healthList = serverMemberManager.members();
    }
}
